import torch
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import time
10wk-2: 순환신경망 (3)
RNN (1)– AbAcAd예제(2)
강의영상
https://youtube.com/playlist?list=PLQqh36zP38-wZO0M4cNFxymfrAumCpRM8
import
Define some funtions
def f(txt,mapping):
return [mapping[key] for key in txt]
= torch.nn.Softmax(dim=1) soft
예비학습: net.parameters()
의 의미
9월27일 강의노트 중 “net.parameters()
의 의미?”를 설명한다.
-
iterator, generator의 개념필요
-
탐구시작: 네트워크 생성
= torch.nn.Linear(in_features=1,out_features=1)
net net.weight
Parameter containing:
tensor([[0.4607]], requires_grad=True)
net.bias
Parameter containing:
tensor([-0.1656], requires_grad=True)
-
torch.optim.SGD? 를 확인하면 params에 대한설명에 아래와 같이 되어있음
params (iterable): iterable of parameters to optimize or dicts defining
parameter groups
-
설명을 읽어보면 params에 iterable object를 넣으라고 되어있음 (iterable object는 숨겨진 명령어로 __iter__
를 가지고 있는 오브젝트를 의미)
set(dir(net.parameters())) & {'__iter__'}
{'__iter__'}
-
무슨의미?
for param in net.parameters():
print(param)
Parameter containing:
tensor([[0.4607]], requires_grad=True)
Parameter containing:
tensor([-0.1656], requires_grad=True)
-
그냥 이건 이런느낌인데?
for param in [net.weight,net.bias]:
print(param)
Parameter containing:
tensor([[0.4607]], requires_grad=True)
Parameter containing:
tensor([-0.1656], requires_grad=True)
결론: net.parameters()
는 net오브젝트에서 학습할 파라메터를 모두 모아 리스트같은 iterable object로 만드는 함수라 이해할 수 있다.
-
응용예제1
= pd.read_csv("https://raw.githubusercontent.com/guebin/DL2022/master/posts/II.%20DNN/2022-09-22-regression.csv")
df =torch.tensor(df.x).float().reshape(100,1)
x=torch.tensor(df.y).float().reshape(100,1) y
= torch.tensor(-5.0,requires_grad=True)
b = torch.tensor(10.0,requires_grad=True)
w = torch.optim.SGD([b,w],lr=1/10) ## 이렇게 전달하면 됩니당!! optimizr
'o')
plt.plot(x,y,*x+b).data,'--') plt.plot(x,(w
for epoc in range(30):
## step1
= b+ w*x
yhat ## step2
= torch.mean((y-yhat)**2)
loss ## step3
loss.backward()## step4
optimizr.step() optimizr.zero_grad()
'o')
plt.plot(x,y,*x+b).data,'--') plt.plot(x,(w
-
응용예제2
= pd.read_csv("https://raw.githubusercontent.com/guebin/DL2022/master/posts/II.%20DNN/2022-09-22-regression.csv")
df = torch.tensor(df.x).float().reshape(100,1)
x = torch.tensor(df.y).float().reshape(100,1)
y = torch.concat([torch.ones_like(x),x],axis=1) X
= torch.tensor([[-5.0],[10.0]],requires_grad=True)
What = torch.optim.SGD([What],lr=1/10) # What은 iterable 하지 않지만 [What]은 iterable 함 optimizr
What
tensor([[-5.],
[10.]], requires_grad=True)
'o')
plt.plot(x,y,@What).data,'--') plt.plot(x,(X
for epoc in range(30):
## step1
= X@What
yhat ## step2
= torch.mean((y-yhat)**2)
loss ## step3
loss.backward()## step4
optimizr.step() optimizr.zero_grad()
'o')
plt.plot(x,y,@What).data,'--') plt.plot(x,(X
Exam4: AbAcAd (2)
data
-
기존의 정리방식
= list('AbAcAd')*100
txt 10] txt[:
['A', 'b', 'A', 'c', 'A', 'd', 'A', 'b', 'A', 'c']
= txt[:-1]
txt_x = txt[1:] txt_y
5],txt_y[:5] txt_x[:
(['A', 'b', 'A', 'c', 'A'], ['b', 'A', 'c', 'A', 'd'])
= torch.tensor(f(txt_x,{'A':0,'b':1,'c':2,'d':3}))
x = torch.tensor(f(txt_y,{'A':0,'b':1,'c':2,'d':3})) y
8],y[:8] x[:
(tensor([0, 1, 0, 2, 0, 3, 0, 1]), tensor([1, 0, 2, 0, 3, 0, 1, 0]))
-
이번엔 원핫인코딩형태까지 미리 정리하자. (임베딩 레이어 안쓸예정)
= torch.nn.functional.one_hot(x).float()
x= torch.nn.functional.one_hot(y).float() y
x,y
(tensor([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[1., 0., 0., 0.],
...,
[1., 0., 0., 0.],
[0., 0., 1., 0.],
[1., 0., 0., 0.]]),
tensor([[0., 1., 0., 0.],
[1., 0., 0., 0.],
[0., 0., 1., 0.],
...,
[0., 0., 1., 0.],
[1., 0., 0., 0.],
[0., 0., 0., 1.]]))
실패했던 풀이: 구현1
-
저번시간의 실패한 풀이
43052)
torch.manual_seed(= torch.nn.Sequential(
net =4,embedding_dim=2),
torch.nn.Embedding(num_embeddings
torch.nn.Tanh(),=2,out_features=4)
torch.nn.Linear(in_features
)= torch.nn.CrossEntropyLoss()
loss_fn = torch.optim.Adam(net.parameters()) optimizr
-
Tanh까지만 클래스로 바꾸어서 구현
class Hnet(torch.nn.Module):
def __init__(self):
super().__init__()
self.i2h = torch.nn.Linear(in_features=4,out_features=2)
self.tanh = torch.nn.Tanh()
def forward(self,x):
= self.tanh(self.i2h(x))
hidden return hidden
-
for문돌릴준비
43052)
torch.manual_seed(= Hnet()
hnet = torch.nn.Linear(in_features=2,out_features=4)
linr = torch.nn.CrossEntropyLoss()
loss_fn = torch.optim.Adam(list(hnet.parameters())+list(linr.parameters())) optimizr
-
for문: 20회반복
for epoc in range(20):
## 1
## 2
= hnet(x)
hidden = linr(hidden)
output = loss_fn(output,y)
loss ## 3
loss.backward()## 4
optimizr.step() optimizr.zero_grad()
-
linr(hnet(x)) 적합결과 <– 숫자체크
linr(hnet(x))
tensor([[-0.3589, 0.7921, -0.1970, -0.0302],
[-0.2912, 0.8140, -0.2032, 0.0178],
[-0.3589, 0.7921, -0.1970, -0.0302],
...,
[-0.3589, 0.7921, -0.1970, -0.0302],
[-0.1065, 0.6307, -0.0874, 0.1821],
[-0.3589, 0.7921, -0.1970, -0.0302]], grad_fn=<AddmmBackward0>)
실패했던 풀이: 구현2
-
Tanh까지 구현한 클래스
# class Hnet(torch.nn.Module):
# def __init__(self):
# super().__init__()
# self.i2h = torch.nn.Linear(in_features=4,out_features=2)
# self.tanh = torch.nn.Tanh()
# def forward(self,x):
# hidden = self.tanh(self.i2h(x))
# return hidden
-
for문돌릴준비
43052)
torch.manual_seed(= Hnet()
hnet = torch.nn.Linear(in_features=2,out_features=4)
linr = torch.nn.CrossEntropyLoss()
loss_fn = torch.optim.Adam(list(hnet.parameters())+list(linr.parameters())) optimizr
-
for문: 20회 반복
= len(x)
T for epoc in range(20):
## 1~2
= 0
loss for t in range(T):
= x[[t]], y[[t]]
xt,yt = hnet(xt)
ht = linr(ht)
ot = loss + loss_fn(ot,yt)
loss ## 3
loss.backward()## 4
optimizr.step() optimizr.zero_grad()
-
linr(hnet(x)) 적합결과 <– 숫자체크
linr(hnet(x))
tensor([[-0.3589, 0.7921, -0.1970, -0.0302],
[-0.2912, 0.8140, -0.2032, 0.0178],
[-0.3589, 0.7921, -0.1970, -0.0302],
...,
[-0.3589, 0.7921, -0.1970, -0.0302],
[-0.1065, 0.6307, -0.0874, 0.1821],
[-0.3589, 0.7921, -0.1970, -0.0302]], grad_fn=<AddmmBackward0>)
순환신경망의 아이디어
모티브
(예비생각1)
결론: 사실
(예비생각2) 수백년전통을 이어가는 방법
“1리터에 500만원에 낙찰된 적 있습니다.”
“2kg에 1억원 정도 추산됩니다.”
“20여 종 종자장을 블렌딩해 100ml에 5000만원씩 분양 예정입니다.”
모두 씨간장(종자장) 가격에 관한 실제 일화다.
(중략...)
위스키나 와인처럼 블렌딩을 하기도 한다.
새로 담근 간장에 씨간장을 넣거나, 씨간장독에 햇간장을 넣어 맛을 유지하기도 한다.
이를 겹장(또는 덧장)이라 한다.
몇몇 종갓집에선 씨간장 잇기를 몇백 년째 해오고 있다.
매년 새로 간장을 담가야 이어갈 수 있으니 불씨 꺼트리지 않는 것처럼 굉장히 어려운 일이다.
이렇게 하는 이유는 집집마다 내려오는 고유 장맛을 잃지 않기 위함이다.
씨간장이란 그만큼 소중한 주방의 자산이며 정체성이다.
덧장: 새로운간장을 만들때, 옛날간장을 섞어서 만듬
*
기존방식 -
*
수백년 전통의 간장맛을 유지하는 방식
*
수백년 전통의 간장맛을 유지하면서 조리를 한다면?
점점 맛있는 간장계란밥이 탄생함
*
알고리즘의 편의상 아래와 같이 생각해도 무방
,
아이디어
*
수백년 전통의 간장맛을 유지하면서 조리하는 과정을 수식으로?
이제 우리가 배울것은 (1) “숙성
하는 방법 (2) “조리
하는 방법이다
즉 숙성
담당 네트워크와 조리
담당 네트워크를 각각 만들어 학습하면 된다.
알고리즘
세부적인 알고리즘 (
(1)
(2)
(3)
좀 더 일반화된 알고리즘
(ver1)
init
for
(ver2)
init hidden
for t in 1:T
= tanh(linr(x)+linr(hidden))
hidden = linr(hidden)
output = soft(output) yt_hat
- 코드상으로는
와 의 구분이 교모하게 사라진다. (그래서 오히려 좋아)
전체알고리즘은 대충 아래와 같은 형식으로 구현될 수 있음
class rNNCell(torch.nn.Module):
def __init__(self):
super().__init__()
= torch.nn.Linear(?,?)
linr1 = torch.nn.Linear(?,?)
linr2 = torch.nn.Tanh()
tanh def forward(self,x,hidden):
= tanh(lrnr1(x)+lrnr2(hidden))
hidden return hidden
init ht= rNNCell()
rnncell
for t in 1:T
= x[[t]], y[[t]]
xt, yt = rnncell(xt, ht)
ht = linr(ht)
ot = loss + loss_fn(ot, yt) loss
숙제
아래와 같은 자료가 있다고 가정하자.
= torch.rand([1000,1])*2-1
x = 3.14 + 6.28*x + torch.randn([1000,1]) y
'o',alpha=0.1) plt.plot(x,y,
아래의 모형을 가정하고
아래는 이를 수행하기 위한 코드이다. ???를 적절히 채워서 코드를 완성하라.
= torch.tensor([0.5], requires_grad=True)
alpha0 = torch.tensor([[0.5]], requires_grad=True)
alpha1 = torch.tensor([0.7], requires_grad=True)
beta0 = torch.tensor([[0.7]], requires_grad=True) beta1
= torch.nn.MSELoss()
loss_fn = torch.optim.SGD(????, lr=1/10) optimizr
for epoc in range(30):
## 1
= alpha0 + beta0 + alpha1*x + beta1*x
yhat ## 2
= loss_fn(yhat,y)
loss ## 3
loss.backward()## 4
optimizr.step() optimizr.zero_grad()
print(alpha0+beta0)
tensor([3.1058], grad_fn=<AddBackward0>)
- 3.14 근처
print(alpha1+beta1)
tensor([[6.2665]], grad_fn=<AddBackward0>)
- 6.28 근처